/**
* 意见反馈提交页面
*
* 功能特性：
* - 提供完整的意见反馈表单，包含标题、类型、内容、图片上传等字段
* - 支持表单验证、图片上传、匿名提交等功能
* - 提供友好的用户交互和错误提示
* - 支持表单数据的本地验证和提交确认
* - 集成腾讯云COS图片上传功能
*
* 技术特性：
* - 使用Vue 3 Composition API
* - 响应式表单数据管理
* - 实时表单验证
* - 图片上传进度显示
* - 防重复提交机制
*
* 使用场景：
* - 用户提交意见反馈
* - 功能建议、体验问题、程序故障等反馈类型
* - 支持匿名和实名提交
*/
<template>
    <view class="submit-page" :style="pageStyle">
        <!-- 头部区域 -->
        <page-header class="header" title="意见反馈" :backgroundColor="headerBgColor"
            @heightChange="handleHeaderHeightChange">
        </page-header>

        <!-- 内容区域 -->
        <view class="content">
            <!-- 意见标题：必填，5-20字 -->
            <view class="form-item">
                <text class="form-label required">意见标题</text>
                <input class="form-input" type="text" placeholder="简明扼要的标题（5-20字）" v-model="formData.noteTitle"
                    :maxlength="20" @blur="validateTitle" />
                <view class="error-wrapper" v-if="errors.noteTitle">
                    <text class="error-tip">{{ errors.noteTitle }}</text>
                </view>
            </view>

            <!-- 意见类型：必选，四种类型供选择 -->
            <view class="form-item">
                <text class="form-label required">意见类型</text>
                <view class="type-selector">
                    <view v-for="(type, index) in feedbackTypes" :key="index" class="type-item"
                        :class="{ 'selected': formData.noteType === type.value }" @click="selectType(type.value)">
                        <uni-icons :type="type.icon" size="18" :color="getIconColor(type.value)"></uni-icons>
                        <text>{{ type.label }}</text>
                    </view>
                </view>
                <view class="error-wrapper" v-if="errors.noteType">
                    <text class="error-tip">{{ errors.noteType }}</text>
                </view>
            </view>

            <!-- 意见内容：必填，10-200字，支持字数统计 -->
            <view class="form-item">
                <text class="form-label required">意见内容</text>
                <textarea class="form-textarea" placeholder="请描述您遇到的问题或建议（10-200字）" v-model="formData.noteContent"
                    :maxlength="200" @blur="validateContent" />
                <view class="char-counter">
                    <text>{{ formData.noteContent.length }}/200</text>
                </view>
                <view class="error-wrapper" v-if="errors.noteContent">
                    <text class="error-tip">{{ errors.noteContent }}</text>
                </view>
            </view>

            <!-- 相关图片：选填，支持多图上传 -->
            <view class="form-item">
                <text class="form-label">相关图片</text>
                <view class="image-upload-container">
                    <view class="image-list">
                        <view v-for="(image, index) in uploadedImages" :key="index" class="image-item">
                            <image class="uploaded-image" :src="image.signedUrl" mode="aspectFill"
                                @click="handleImagePreviewResponse(index)" />
                            <view class="image-delete-btn" @click="handleImageDeleteButtonClick(index)">
                                <uni-icons type="close" size="16" color="#fff"></uni-icons>
                            </view>
                        </view>
                        <view v-if="uploadedImages.length < maxImageCount" class="upload-btn"
                            @click="handleImageChooseButtonClick()">
                            <uni-icons type="camera" size="32" color="#999"></uni-icons>
                            <text class="upload-text">添加图片</text>
                        </view>
                    </view>

                    <!-- 上传进度显示 -->
                    <view v-if="uploadProgress.isUploading" class="upload-progress">
                        <view class="progress-header">
                            <text class="progress-title">正在上传: {{ uploadProgress.fileName }}</text>
                            <text class="progress-percentage">{{ uploadProgress.percentage }}%</text>
                        </view>
                        <view class="progress-bar">
                            <view class="progress-fill" :style="{ width: uploadProgress.percentage + '%' }"></view>
                        </view>
                        <view class="progress-details">
                            <text class="progress-message">{{ uploadProgress.message }}</text>
                            <text class="progress-stats">
                                {{ uploadProgress.uploadedParts }}/{{ uploadProgress.totalParts }} 分段
                                ({{ formatFileSize(uploadProgress.uploadedBytes) }}/{{
                                    formatFileSize(uploadProgress.totalBytes) }})
                            </text>
                        </view>
                    </view>

                    <view class="upload-tip">
                        <text>最多上传{{ maxImageCount }}张图片，每张不超过5MB</text>
                    </view>
                </view>
                <view class="error-wrapper" v-if="errors.images">
                    <text class="error-tip">{{ errors.images }}</text>
                </view>
            </view>

            <!-- 匿名选项：控制是否记录用户信息 -->
            <view class="form-item checkbox-item">
                <label class="checkbox-label">
                    <switch color="#3c9cff" :checked="formData.isAnonymous" @change="toggleAnonymous" />
                    <text>匿名提交</text>
                </label>
                <text class="tip-text">匿名提交后将不会记录您的个人信息</text>
            </view>

            <!-- 昵称/姓名 -->
            <view class="form-item" v-if="!formData.isAnonymous">
                <text class="form-label required">昵称/姓名</text>
                <input class="form-input" type="text" placeholder="请输入您的昵称或姓名" v-model="formData.nameCn" :maxlength="20"
                    @blur="validateNickname" />
                <view class="error-wrapper" v-if="errors.nameCn">
                    <text class="error-tip">{{ errors.nameCn }}</text>
                </view>
            </view>

            <!-- 联系方式：选填，支持手机号或邮箱 -->
            <view class="form-item" v-if="!formData.isAnonymous">
                <text class="form-label">联系方式</text>
                <input class="form-input" type="text" placeholder="手机号码或邮箱（选填）" v-model="formData.mobliephone"
                    @blur="validateContact" />
                <view class="error-wrapper" v-if="errors.mobliephone">
                    <text class="error-tip">{{ errors.mobliephone }}</text>
                </view>
            </view>

            <!-- 提交按钮 -->
            <view class="form-item submit-item">
                <button class="submit-button" :class="{ 'disabled': isSubmitting || !isFormValid }"
                    :disabled="isSubmitting || !isFormValid" @click.prevent="handleSubmitFormButtonClick">
                    <view class="button-content">
                        <uni-icons v-if="isSubmitting" type="spinner-cycle" size="18" color="#fff"></uni-icons>
                        <text>{{ isSubmitting ? '提交中...' : '提交反馈' }}</text>
                    </view>
                </button>
            </view>
        </view>

        <!-- 提示消息：用于显示操作反馈 -->
        <view v-if="showToast" class="toast" :class="toastType">
            <text>{{ toastMessage }}</text>
        </view>

        <!-- 确认对话框：提交前的二次确认 -->
        <view v-if="showConfirmDialog" class="dialog-mask">
            <view class="dialog-container">
                <view class="dialog-title">
                    <text>确认提交</text>
                </view>
                <view class="dialog-content">
                    <text>提交后将无法修改，确认提交此反馈？</text>
                </view>
                <view class="dialog-buttons">
                    <button class="cancel-button" @click="handleCancelSubmitButtonClick">取消</button>
                    <button class="confirm-button" @click="handleConfirmSubmitButtonClick">确认提交</button>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
import { defineComponent, ref, reactive, computed, onMounted, onUnmounted } from 'vue';
import PageHeader from '/components/PageHeader.vue';
import { myRequest } from '@/library/request.js';
import { API } from '../library/config';
import COS from 'cos-wx-sdk-v5';
import { generateFilePath } from '@/library/tool.js';
import {
    createMultipartUploadManager,
    UPLOAD_CONFIG,
    getUploadCredentials,
    createCOSClient,
    uploadFileToCOS,
    getSignedUrl
} from '@/library/cos.js';
export default defineComponent({
    name: 'Submit',
    components: {
        PageHeader
    },
    setup() {
        // ===== 变量声明 =====

        // 页面样式相关
        const headerBgColor = ref('#ffffff'); // 头部背景色
        const headerInfo = ref(null); // 头部信息
        const footerInfo = ref(null); // 底部信息
        const pageStyle = ref({}); // 页面样式

        // 头部高度相关
        const headerHeight = ref(0); // 头部总高度（px）
        const statusBarHeight = ref(20); // 状态栏高度（px）
        const navBarHeight = ref(44); // 导航栏高度（px）

        // 提交状态相关
        const isSubmitting = ref(false); // 是否正在提交
        const showToast = ref(false); // 是否显示提示消息
        const toastMessage = ref(''); // 提示消息内容
        const toastType = ref('info'); // 提示消息类型
        const showConfirmDialog = ref(false); // 是否显示确认对话框
        const submittedIds = ref(new Set()); // 已提交的ID集合，防止重复提交
        let toastTimer = null; // 提示消息定时器
        let submitDebounceTimer = null; // 提交防抖定时器

        // 图片上传相关配置
        const maxImageSize = 5 * 1024 * 1024; // 最大图片大小（5MB）
        const maxImageCount = ref(6); // 最大图片数量

        // 已上传的图片数组
        const uploadedImages = ref([]); // 已上传的图片列表

        // COS上传相关
        const uploadCredentials = ref(null); // COS上传秘钥
        const isUploadCredentialsLoading = ref(false); // 是否正在加载上传秘钥

        // 上传进度相关
        const uploadProgress = ref({
            isUploading: false, // 是否正在上传
            percentage: 0, // 上传进度百分比
            message: '', // 上传状态消息
            fileName: '', // 当前上传文件名
            uploadedBytes: 0, // 已上传字节数
            totalBytes: 0, // 总字节数
            uploadedParts: 0, // 已上传分片数
            totalParts: 0 // 总分片数
        });

        // 表单数据
        const formData = reactive({
            noteTitle: '', // 反馈标题
            noteType: '', // 反馈类型
            noteContent: '', // 反馈内容
            noteImages: '', // 需要上传的图片，字符串，用分号隔开，最多6张
            nameCn: '', // 用户昵称
            mobliephone: '', // 用户联系方式
            isAnonymous: false, // 是否匿名提交
        });

        // 错误信息
        const errors = reactive({
            noteTitle: '', // 标题错误信息
            noteType: '', // 类型错误信息
            noteContent: '', // 内容错误信息
            nameCn: '', // 昵称错误信息
            mobliephone: '', // 联系方式错误信息
            images: '' // 图片错误信息
        });

        // ===== 计算属性 =====

        /**
         * 表单验证状态
         * 检查所有必填字段是否已填写且符合要求
         */
        const isFormValid = computed(() => {
            const baseValid = formData.noteTitle.length >= 5 &&
                formData.noteType !== '' &&
                formData.noteContent.length >= 10;

            // 非匿名时需要验证昵称
            if (!formData.isAnonymous) {
                return baseValid && formData.nameCn.length >= 2;
            }

            return baseValid;
        });

        // ===== 反馈类型配置 =====

        /**
         * 反馈类型配置
         * 定义可选的反馈类型及其对应的图标和值
         * 留言类型:0=其他,1=建议,2=BUG,3=投诉
         */
        const feedbackTypes = [
            { label: '其他', value: 0, key: 'feature', icon: 'star' },
            { label: '建议', value: 1, key: 'experience', icon: 'help' },
            { label: 'BUG', value: 2, key: 'bug', icon: 'info' },
            { label: '投诉', value: 3, key: 'other', icon: 'chat' }
        ];

        // ===== 页面交互方法 =====

        /**
         * 头部高度变化处理
         * 动态调整页面布局以适应不同设备的头部高度
         * @param {Object} heightInfo - 头部高度信息对象
         */
        const handleHeaderHeightChange = (heightInfo) => {
            statusBarHeight.value = heightInfo.statusBarHeight || 20;
            navBarHeight.value = heightInfo.navBarHeight || 44;
            headerHeight.value = heightInfo.totalHeaderHeight || (statusBarHeight.value + navBarHeight.value);

            console.log('头部高度更新:', heightInfo, '总高度px:', headerHeight.value);
        };

        /**
         * 返回按钮点击处理
         * 检查是否有未提交的内容，如有则提示用户确认
         */
        const handleToBackPageButtonClick = () => {
            if (formData.noteTitle || formData.noteContent) {
                uni.showModal({
                    title: '提示',
                    content: '您填写的内容尚未提交，确定要离开吗？',
                    success: (res) => {
                        if (res.confirm) {
                            uni.navigateBack();
                        }
                    }
                });
            } else {
                uni.navigateBack();
            }
        };

        /**
         * 表单提交按钮点击处理
         * 验证表单数据，防抖处理，显示确认对话框
         */
        const handleSubmitFormButtonClick = () => {
            validateFormData();
            if (!isFormValid.value) {
                showToastMessage('请完善表单信息', 'error');
                return;
            }

            if (submitDebounceTimer) {
                clearTimeout(submitDebounceTimer);
            }

            submitDebounceTimer = setTimeout(() => {
                showConfirmDialog.value = true;
            }, 300);
        };

        /**
         * 确认提交按钮点击处理
         * 执行实际的表单提交操作，包含防重复提交和数据序列化验证
         */
        const handleConfirmSubmitButtonClick = () => {
            showConfirmDialog.value = false;
            const submitId = generateSubmitId();
            if (submittedIds.value.has(submitId)) {
                showToastMessage('请勿重复提交', 'warning');
                return;
            }

            isSubmitting.value = true;

            // 处理图片数据，转换为分号分隔的字符串
            const submitImages = uploadedImages.value.map(img => img.filePath).join(';');

            // 准备提交的数据 - 确保所有数据都是可序列化的
            const submitData = {
                note_title: String(formData.noteTitle || ''),
                note_type: Number(formData.noteType) || 0,
                note_content: String(formData.noteContent || ''),
                note_images: String(submitImages || ''),
                name_cn: String(formData.isAnonymous ? '' : (formData.nameCn || '')),
                phone: String(formData.isAnonymous ? '' : (formData.mobliephone || '')),
            };

            // 验证数据是否可序列化
            try {
                JSON.stringify(submitData);
                console.log('准备提交的数据:', submitData);
            } catch (error) {
                console.error('数据序列化失败:', error);
                showToastMessage('数据格式错误，请重试', 'error');
                isSubmitting.value = false;
                return;
            }

            myRequest({
                url: API.createNote,
                method: 'POST',
                data: submitData
            }).then(res => {
                console.log('提交数据成功:', res);
                if (res.code === 200) {
                    showToastMessage('提交成功', 'success');
                    uni.navigateBack();
                } else {
                    showToastMessage('提交失败: ' + res.message, 'error');
                }
            }).catch(err => {
                console.error('提交数据失败:', err);
                showToastMessage('提交失败: ' + (err.message || err.errMsg || '网络错误'), 'error');
            }).finally(() => {
                isSubmitting.value = false;
            });
        };

        /**
         * 取消提交按钮点击处理
         * 关闭确认对话框，不执行提交操作
         */
        const handleCancelSubmitButtonClick = () => {
            showConfirmDialog.value = false;
        };

        // ===== 表单验证方法 =====

        /**
         * 验证反馈标题
         * 要求：5-20字，必填
         */
        const validateTitle = () => {
            if (!formData.noteTitle) {
                errors.noteTitle = '请填写反馈标题';
            } else if (formData.noteTitle.length < 5) {
                errors.noteTitle = '标题至少需要5个字';
            } else {
                errors.noteTitle = '';
            }
        };

        /**
         * 验证反馈内容
         * 要求：10-200字，必填
         */
        const validateContent = () => {
            if (!formData.noteContent) {
                errors.noteContent = '请填写反馈内容';
            } else if (formData.noteContent.length < 10) {
                errors.noteContent = '内容至少需要10个字';
            } else {
                errors.noteContent = '';
            }
        };

        /**
         * 验证联系方式
         * 支持：手机号或邮箱，选填
         */
        const validateContact = () => {
            if (formData.mobliephone) {
                const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
                const phoneRegex = /^1[3-9]\d{9}$/;

                if (!emailRegex.test(formData.mobliephone) && !phoneRegex.test(formData.mobliephone)) {
                    errors.mobliephone = '请输入有效的手机号或邮箱';
                } else {
                    errors.mobliephone = '';
                }
            } else {
                errors.mobliephone = '';
            }
        };

        /**
         * 验证用户昵称
         * 要求：2-20字，非匿名时必填
         */
        const validateNickname = () => {
            if (!formData.isAnonymous) {
                if (!formData.nameCn) {
                    errors.nameCn = '请填写昵称或姓名';
                } else if (formData.nameCn.length < 2) {
                    errors.nameCn = '昵称至少需要2个字';
                } else {
                    errors.nameCn = '';
                }
            }
        };

        // ===== 表单交互方法 =====

        /**
         * 选择反馈类型
         * 更新表单数据并清除相关错误信息
         * @param {string} type - 反馈类型值
         */
        const selectType = (type) => {
            formData.noteType = type;
            errors.noteType = '';
        };

        /**
         * 切换匿名提交状态
         * 匿名时清空个人信息相关字段
         * @param {Event} e - 开关事件对象
         */
        const toggleAnonymous = (e) => {
            formData.isAnonymous = e.detail.value;
            if (formData.isAnonymous) {
                // 匿名时清空个人信息
                formData.nameCn = '';
                formData.mobliephone = '';
                errors.nameCn = '';
                errors.mobliephone = '';
            }
        };

        /**
         * 获取反馈类型图标颜色
         * 根据选中状态返回不同的颜色
         * @param {string} typeValue - 反馈类型值
         * @returns {string} 图标颜色
         */
        const getIconColor = (typeValue) => {
            return formData.noteType === typeValue ? '#3c9cff' : '#666';
        };

        // ===== 图片处理方法 =====

        /**
         * 处理图片预览响应
         * 使用uni-app的图片预览功能
         * @param {number} index - 图片索引
         */
        const handleImagePreviewResponse = (index) => {
            const urls = uploadedImages.value.map(img => img.signedUrl);
            uni.previewImage({
                current: index,
                urls: urls,
                fail: (err) => {
                    console.error('预览图片失败:', err);
                    showToastMessage('预览图片失败', 'error');
                }
            });
        };

        /**
         * 处理图片删除按钮点击
         * 从已上传图片列表中移除指定图片
         * @param {number} index - 图片索引
         */
        const handleImageDeleteButtonClick = (index) => {
            uploadedImages.value.splice(index, 1);
            errors.images = '';
        };

        /**
         * 处理图片选择按钮点击
         * 调用系统图片选择器，支持相册和相机
         */
        const handleImageChooseButtonClick = () => {
            if (uploadedImages.value.length >= maxImageCount.value) {
                showToastMessage('已达到最大图片数量限制', 'warning');
                return;
            }
            uni.chooseImage({
                sizeType: ['original', 'compressed'],
                sourceType: ['album', 'camera'],
                count: maxImageCount.value - uploadedImages.value.length,
                success: (res) => {
                    handleImageSelectedResponse(res.tempFilePaths);
                },
                fail: (err) => {
                    console.error('选择图片失败:', err);
                    showToastMessage('选择图片失败', 'error');
                }
            });
        };


        /**
         * 处理图片选择响应
         * 检查上传凭证有效性，然后执行上传操作
         * @param {Array} tempFilePaths - 临时文件路径数组
         */
        const handleImageSelectedResponse = async (tempFilePaths) => {
            let credentials = uni.getStorageSync('uploadCredentials');
            if (credentials &&
                credentials.ExpiredTime &&
                credentials.ExpiredTime * 1000 > new Date().getTime()) {
                // 凭证有效
                uploadWithCredentials(tempFilePaths, credentials);
            } else {
                getUploadCredentials().then(res => {
                    credentials = res;
                    uploadWithCredentials(tempFilePaths, credentials);
                });
            }
        };

        /**
         * 使用凭证上传文件到COS
         * 支持进度显示和错误处理
         * @param {Array} tempFilePaths - 临时文件路径数组
         * @param {Object} cosCredentials - COS访问凭证
         */
        const uploadWithCredentials = (tempFilePaths, cosCredentials) => {
            console.log('tempFilePaths:', tempFilePaths[0]);
            uploadFileToCOS({
                localFilePath: tempFilePaths[0],
                fileType: 'image',
                moduleType: 'note',
                credentials: cosCredentials,
                onProgress: (progressInfo) => {
                    console.log('文件上传进度:', progressInfo);

                    // 更新上传进度显示
                    uploadProgress.value = {
                        isUploading: true,
                        percentage: progressInfo.percentage,
                        message: progressInfo.message,
                        fileName: progressInfo.fileName,
                        uploadedBytes: progressInfo.loadedBytes,
                        totalBytes: progressInfo.totalBytes
                    };
                },
                onSuccess: (uploadResult) => {
                    console.log('文件上传成功:', uploadResult);
                    // 重置上传进度
                    uploadProgress.value.isUploading = false;

                    // 显示成功提示
                    showToastMessage('图片上传成功', 'success');
                    const viewCredentials = uni.getStorageSync('viewCredentials');
                    getSignedUrl(uploadResult.fullPath, viewCredentials).then(res => {
                        console.log('文件URL:', res);
                        uploadedImages.value.push({
                            signedUrl: res,
                            fileName: uploadResult.fileName,
                            filePath: uploadResult.fullPath,
                        });
                    });
                },
                onError: (errorInfo) => {
                    console.error('文件上传失败:', errorInfo);

                    // 重置上传进度
                    uploadProgress.value.isUploading = false;

                    // 显示错误提示
                    showToastMessage('图片上传失败: ' + errorInfo.message, 'error');
                }
            });
        };
        // ===== 工具方法 =====

        /**
         * 生成提交ID
         * 用于防止重复提交，基于标题和时间戳生成唯一标识
         * @returns {string} 提交ID
         */
        const generateSubmitId = () => {
            return formData.noteTitle + '_' + new Date().getTime();
        };

        /**
         * 显示提示消息
         * 支持不同类型的提示消息，自动消失
         * @param {string} message - 提示内容
         * @param {string} type - 提示类型：info/warning/error
         */
        const showToastMessage = (message, type = 'info') => {
            if (toastTimer) {
                clearTimeout(toastTimer);
            }
            toastMessage.value = message;
            toastType.value = type;
            showToast.value = true;

            toastTimer = setTimeout(() => {
                showToast.value = false;
            }, 2000);
        };

        /**
         * 格式化文件大小
         * 将字节数转换为可读的文件大小格式
         * @param {number} bytes - 字节数
         * @returns {string} 格式化后的文件大小字符串
         */
        const formatFileSize = (bytes) => {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        };

        /**
         * 初始化页面设备适配信息
         * 预留方法，用于后续设备适配功能
         */
        const initDeviceAdaptation = () => {
            // TODO: 实现设备适配逻辑
        };

        /**
         * 验证所有表单数据
         * 调用所有验证方法，确保表单数据完整性
         */
        const validateFormData = () => {
            validateTitle();
            validateContent();
            validateNickname();
            validateContact();
        };

        // ===== 生命周期钩子 =====

        /**
         * 组件挂载时执行
         * 初始化页面相关配置
         */
        onMounted(() => {
            // 初始化设备适配信息
            initDeviceAdaptation();
        });

        /**
         * 组件卸载时执行
         * 清理定时器和监听器，防止内存泄漏
         */
        onUnmounted(() => {
            // 清理定时器
            if (toastTimer) {
                clearTimeout(toastTimer);
            }
            if (submitDebounceTimer) {
                clearTimeout(submitDebounceTimer);
            }
        });

        return {
            // ===== 变量 =====
            headerBgColor,
            formData,
            feedbackTypes,
            isSubmitting,
            errors,
            isFormValid,
            showToast,
            toastMessage,
            toastType,
            showConfirmDialog,
            pageStyle,
            headerHeight,
            statusBarHeight,
            navBarHeight,
            maxImageCount,
            uploadedImages,
            uploadCredentials,
            isUploadCredentialsLoading,
            uploadProgress,

            // ===== 方法 =====
            handleHeaderHeightChange,
            handleToBackPageButtonClick,
            handleSubmitFormButtonClick,
            handleConfirmSubmitButtonClick,
            handleCancelSubmitButtonClick,
            validateTitle,
            validateContent,
            validateContact,
            validateNickname,
            validateFormData,
            selectType,
            toggleAnonymous,
            generateSubmitId,
            showToastMessage,
            getIconColor,
            handleImagePreviewResponse,
            handleImageDeleteButtonClick,
            handleImageChooseButtonClick,
            formatFileSize,
        };
    }
});
</script>

<style lang="less" scoped>
.submit-page {
    width: 100vw;
    min-height: calc(100vh - v-bind('headerHeight + "px"'));
    display: flex;
    flex-direction: column;
    background-color: #f8f8f8;
    padding-top: v-bind('headerHeight + "px"'); // 动态头部高度

    .content {
        flex: 1;
        overflow-y: auto;
        background-color: #f8f8f8;
        padding: 20rpx;

        .form-item {
            margin-bottom: 24rpx;
            position: relative;
            background-color: #fff;
            border-radius: 12rpx;
            padding: 20rpx 16rpx 24rpx;
            box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);

            .form-label {
                display: block;
                font-size: 28rpx;
                color: #333;
                margin-bottom: 12rpx;
                font-weight: 500;
                padding-left: 10rpx;
                border-left: 4rpx solid #3c9cff;

                &.required:after {
                    content: '*';
                    color: #ff4d4f;
                    margin-left: 6rpx;
                }
            }

            .form-input {
                width: 100%;
                height: 76rpx;
                background-color: #f9f9f9;
                border-radius: 8rpx;
                border: 1px solid #eaeaea;
                padding: 0 20rpx;
                box-sizing: border-box;
                font-size: 28rpx;
            }

            .form-textarea {
                width: 100%;
                height: 220rpx;
                background-color: #f9f9f9;
                border-radius: 8rpx;
                border: 1px solid #eaeaea;
                padding: 16rpx;
                box-sizing: border-box;
                font-size: 28rpx;
            }

            .char-counter {
                text-align: right;
                padding: 6rpx 10rpx 0 0;
                color: #999;
                font-size: 24rpx;
                height: 36rpx;
            }

            .tip-text {
                font-size: 24rpx;
                color: #999999;
                margin-top: 8rpx;
                padding-left: 10rpx;
            }

            .error-wrapper {
                margin-top: 8rpx;

                .error-tip {
                    font-size: 24rpx;
                    color: #ff4d4f;
                    padding: 2rpx 8rpx;
                    position: relative;
                    display: inline-block;
                    line-height: 1.4;
                }
            }

            .type-selector {
                display: flex;
                flex-wrap: wrap;
                background-color: #fff;
                border-radius: 8rpx;
                overflow: hidden;
                margin-bottom: 8rpx;

                .type-item {
                    width: 25%;
                    height: 110rpx;
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                    font-size: 24rpx;
                    color: #666;
                    gap: 8rpx;
                    border: 1px solid #f5f5f5;
                    box-sizing: border-box;
                    transition: all 0.3s;

                    &.selected {
                        color: #3c9cff;
                        background-color: rgba(60, 156, 255, 0.1);
                        transform: scale(1.02);
                    }
                }
            }

            &.checkbox-item {
                display: flex;
                flex-direction: column;

                .checkbox-label {
                    display: flex;
                    align-items: center;
                    font-size: 28rpx;
                    color: #333;

                    text {
                        margin-left: 12rpx;
                    }
                }
            }

            &.submit-item {
                margin-top: 40rpx;
                margin-bottom: 40rpx;
                padding: 0;

                .submit-button {
                    width: 100%;
                    height: 88rpx;
                    border-radius: 44rpx;
                    background: linear-gradient(135deg, #3c9cff 0%, #5eacff 100%);
                    border: none;
                    color: #ffffff;
                    font-size: 32rpx;
                    font-weight: 500;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    transition: all 0.3s ease;
                    box-shadow: 0 8rpx 16rpx rgba(60, 156, 255, 0.3);

                    .button-content {
                        display: flex;
                        align-items: center;
                        gap: 8rpx;

                        text {
                            line-height: 1;
                        }
                    }

                    &:active {
                        transform: scale(0.98);
                        box-shadow: 0 4rpx 8rpx rgba(60, 156, 255, 0.2);
                    }

                    &.disabled {
                        opacity: 0.6;
                        background: linear-gradient(135deg, #cccccc 0%, #dddddd 100%);
                        box-shadow: none;
                        transform: none;
                    }
                }
            }
        }

        .image-upload-container {
            margin-top: 16rpx;

            .image-list {
                display: flex;
                flex-wrap: wrap;
                gap: 16rpx;
                margin-bottom: 12rpx;

                .image-item {
                    position: relative;
                    width: 160rpx;
                    height: 160rpx;
                    border-radius: 8rpx;
                    overflow: hidden;
                    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);

                    .uploaded-image {
                        width: 100%;
                        height: 100%;
                        border-radius: 8rpx;
                    }

                    .image-delete-btn {
                        position: absolute;
                        top: 8rpx;
                        right: 8rpx;
                        width: 32rpx;
                        height: 32rpx;
                        background-color: rgba(0, 0, 0, 0.6);
                        border-radius: 50%;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        z-index: 10;
                    }
                }

                .upload-btn {
                    width: 160rpx;
                    height: 160rpx;
                    border: 2rpx dashed #ddd;
                    border-radius: 8rpx;
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;
                    background-color: #fafafa;
                    transition: all 0.3s;

                    &:active {
                        background-color: #f0f0f0;
                        border-color: #ccc;
                    }

                    .upload-text {
                        font-size: 24rpx;
                        color: #999;
                        margin-top: 8rpx;
                    }
                }
            }

            .upload-tip {
                font-size: 24rpx;
                color: #999;
                padding-left: 10rpx;
            }

            /* 上传进度显示 */
            .upload-progress {
                margin-top: 20rpx;
                padding: 20rpx;
                background-color: #f8f9fa;
                border-radius: 12rpx;
                border: 1px solid #e9ecef;

                .progress-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 12rpx;

                    .progress-title {
                        font-size: 26rpx;
                        color: #333;
                        font-weight: 500;
                    }

                    .progress-percentage {
                        font-size: 24rpx;
                        color: #3c9cff;
                        font-weight: bold;
                    }
                }

                .progress-bar {
                    width: 100%;
                    height: 8rpx;
                    background-color: #e9ecef;
                    border-radius: 4rpx;
                    overflow: hidden;
                    margin-bottom: 12rpx;

                    .progress-fill {
                        height: 100%;
                        background: linear-gradient(90deg, #3c9cff 0%, #5eacff 100%);
                        border-radius: 4rpx;
                        transition: width 0.3s ease;
                    }
                }

                .progress-details {
                    display: flex;
                    flex-direction: column;
                    gap: 4rpx;

                    .progress-message {
                        font-size: 24rpx;
                        color: #666;
                    }

                    .progress-stats {
                        font-size: 22rpx;
                        color: #999;
                    }
                }
            }
        }

    }



    /* 提示消息 */
    .toast {
        position: fixed;
        left: 50%;
        transform: translateX(-50%);
        top: calc(var(--status-bar-height) + 130rpx);
        padding: 20rpx 40rpx;
        border-radius: 40rpx;
        background-color: rgba(0, 0, 0, 0.7);
        color: #fff;
        font-size: 28rpx;
        z-index: 1000;
        animation: fadeInDown 0.3s, fadeOut 0.3s 1.7s;
        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
        max-width: 80%;

        &.info {
            background-color: rgba(0, 0, 0, 0.7);
        }

        &.warning {
            background-color: rgba(240, 173, 78, 0.9);
        }

        &.error {
            background-color: rgba(221, 82, 77, 0.95);
        }
    }

    /* 确认对话框 */
    .dialog-mask {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background-color: rgba(0, 0, 0, 0.6);
        z-index: 9998;
        display: flex;
        justify-content: center;
        align-items: center;

        .dialog-container {
            width: 560rpx;
            background-color: #fff;
            border-radius: 16rpx;
            overflow: hidden;
            box-shadow: 0 6rpx 30rpx rgba(0, 0, 0, 0.1);

            .dialog-title {
                padding: 30rpx 0;
                text-align: center;
                font-size: 32rpx;
                font-weight: 500;
                color: #333;
                border-bottom: 1px solid #f0f0f0;
            }

            .dialog-content {
                padding: 40rpx 30rpx;
                text-align: center;
                font-size: 28rpx;
                color: #666;
            }

            .dialog-buttons {
                display: flex;
                border-top: 1px solid #f0f0f0;

                button {
                    flex: 1;
                    height: 90rpx;
                    margin: 0;
                    font-size: 28rpx;
                    border-radius: 0;
                    line-height: 90rpx;

                    &.cancel-button {
                        color: #666;
                        background-color: #fff;
                        border-right: 1px solid #f0f0f0;
                    }

                    &.confirm-button {
                        color: #3c9cff;
                        background-color: #fff;
                    }
                }
            }
        }
    }

    /* 动画 */
    @keyframes fadeInDown {
        from {
            opacity: 0;
            transform: translate(-50%, -20rpx);
        }

        to {
            opacity: 1;
            transform: translate(-50%, 0);
        }
    }

    @keyframes fadeOut {
        from {
            opacity: 1;
        }

        to {
            opacity: 0;
        }
    }
}
</style>